#include "max30102.h"
#include "algorithm.h"
#include "OLED.h"
//写Data到max30102中
HAL_StatusTypeDef Max30102_WriteData(uint8_t MemAddress,uint8_t Command,uint16_t SendCount)
{
	HAL_StatusTypeDef status=HAL_OK;
	status=HAL_I2C_Mem_Write(&hi2c2,Max30102_Write_Address,MemAddress,I2C_MEMADD_SIZE_8BIT,&Command,SendCount,100);
	return status;
}

//读出来
HAL_StatusTypeDef Max30102_ReadData(uint8_t DatAddress,uint8_t *Data,uint16_t ReceiveCount)
{
	HAL_StatusTypeDef status=HAL_OK;
	status=HAL_I2C_Mem_Read(&hi2c2,Max30102_Read_Address,DatAddress,I2C_MEMADD_SIZE_8BIT,Data,ReceiveCount,100);
	return status;
}

void Max30102_FIFO_ReadData(uint8_t DatAddress,uint8_t SixData[6],uint16_t Size)
{
	uint8_t temp;
	Max30102_ReadData(REG_INTR_STATUS_1,&temp,1);
	Max30102_ReadData(REG_INTR_STATUS_2,&temp,1);
	Max30102_ReadData(DatAddress,SixData,Size);
}

uint8_t TempData[6];
uint32_t red_buffer[500];  //红光数据red，用于计算心率
uint32_t ir_buffer[500];  //红外数据 ir，用于计算血氧
int32_t ir_buffer_length=500;   //计算前500个样本得到的数据
int32_t pn_SpO2_value;   //血氧实际值
int8_t SpO2_valid;        //血氧值有效标志
int32_t pn_hr_value;    //心率实际值
int8_t hr_valid;         //心率有效标志
uint32_t red_max=0,red_min=0x3FFFF;  //红光取值范围
int num1=0;
uint32_t G_Hr=60;
uint32_t G_SpO2=100;


void Max30102_Calculate_HR_BO_Value(void)
{
	for(int i=0;i<ir_buffer_length;i++)
	{
		while(Max30102_INT==GPIO_PIN_SET); //等待中断引脚相应，默认为高,当触发后会拉低
		Max30102_FIFO_ReadData(REG_FIFO_DATA,TempData,6);
		red_buffer[i]=((TempData[0]&0x03)<<16) | (TempData[1]<<8) | (TempData[2]); //前三位数据组成HR
		ir_buffer[i]=((TempData[3]&0x03)<<16) | (TempData[4]<<8) | (TempData[5]); //后三位数据组成BO
		
	}
	maxim_heart_rate_and_oxygen_saturation(ir_buffer,ir_buffer_length,red_buffer,&pn_SpO2_value,&SpO2_valid,&pn_hr_value,&hr_valid);
	//传入500个采样，通过算法得出实际心率血氧值
	if(hr_valid==1 && SpO2_valid==1 && pn_hr_value<=220)
	{
		G_Hr=pn_hr_value;
		G_SpO2=pn_SpO2_value;
	}
}



void Max30102_Reset(void)
{
	Max30102_WriteData(REG_MODE_CONFIG,0x40,1);
	Max30102_WriteData(REG_MODE_CONFIG,0x40,1);
}

void Max30102_Init(void)
{
	Max30102_Reset();
	
	Max30102_WriteData(REG_INTR_ENABLE_1,0xc0,1);	// INTR setting
	Max30102_WriteData(REG_INTR_ENABLE_2,0x00,1);
	Max30102_WriteData(REG_FIFO_WR_PTR,0x00,1);  	//FIFO_WR_PTR[4:0]
	Max30102_WriteData(REG_OVF_COUNTER,0x00,1);  	//OVF_COUNTER[4:0]
	Max30102_WriteData(REG_FIFO_RD_PTR,0x00,1);  	//FIFO_RD_PTR[4:0]
	Max30102_WriteData(REG_FIFO_CONFIG,0x0f,1);  	//sample avg = 1, fifo rollover=false, fifo almost full = 17
	Max30102_WriteData(REG_MODE_CONFIG,0x03,1);  	//0x02 for Red only, 0x03 for SpO2 mode 0x07 multimode LED
	Max30102_WriteData(REG_SPO2_CONFIG,0x27,1);  	// SPO2_ADC range = 4096nA, SPO2 sample rate (100 Hz), LED pulseWidth (400uS)  
	Max30102_WriteData(REG_LED1_PA,0x24,1);   	//Choose value for ~ 7mA for LED1
	Max30102_WriteData(REG_LED2_PA,0x24,1);   	// Choose value for ~ 7mA for LED2
	Max30102_WriteData(REG_PILOT_PA,0x7f,1);   	// Choose value for ~ 25mA for Pilot LED
}

void Show_HR_BO(void)
{
	OLED_ShowString(4,1,"HR:");
	OLED_ShowString(4,9,"SpO2:");
	
	OLED_ShowFixedLengthNumber(4,4,G_Hr,3);
	OLED_ShowFixedLengthNumber(4,14,G_SpO2,3);
	
}

int GetCurrentHeartRate(void)
{
	return G_Hr;
}



